Initial Setup
if you use GitHub
create a new project using this one as a template.
clone it git clone <project> and navigate to the root folder cd <project>
add a .token file containing your access token to the git repository (allows for git opts to work seamlessly).
run npm run set-git-auth to update your repo's git config to include the token
If your project has private dependencies or publishes to private npm registries, create an .npmrc containing:
@<scope1>:registry=https://<ADDRESS>.com/api/v4/packages/npm/
@<scope2>:registry=https://<ADDRESS>.<DOMAIN>.com/api/v4/packages/npm/
//<ADDRESS>.<DOMAIN>.com/:_authToken=${TOKEN}
//<ADDRESS>.<DOMAIN>.com/api/v4/groups/<GROUP_ID>/packages/npm/:_authToken=${TOKEN}
//<ADDRESS>.<DOMAIN>.com/api/v4/projects/<PROJECT_ID>/packages/npm/:_authToken=${TOKEN}
Changing:
- to `gitlab` or `github` (or other);
to your domain if any (if you are using plain gitlab or GitHub, remove " " and the extra dot); - <GROUP_ID> to your project's group id (if any). otherwise remove this line
- <PROJECT_ID> to your project's id
Installation
Run npm install (or npm run do-install if you have private dependencies and a .token file) to install the dependencies:
If this is the first time you are running this command, it will also (according to your choices:
- update this repository's dependencies to their latest version;
- creates the various token files which you can leave empty unless you have private dependencies or publish to private registries
- delete the
postinstallscript frompackage.json; - try to commit the updated
package.jsonand deleted files (having ssh access helps here);
Scripts
The following npm scripts are available for development:
do-install- sets aTOKENenvironment variable to the contents of.tokenand runs npm install (useful when you have private dependencies);update-scripts: will pull the GitHub actions, templates, and style configs from the for-fabric repository, overwriting the existing.on-first-run: will run the initial setup script,set-git-auth- change git config to include the token (no longer requires manual auth);postinstall- will run only on the first installation to trigger the dep update. Will self-delete;flash-forward- updates all dependencies. Take care, This may not be desirable is some cases;reset- updates all dependencies. Take care, This may not be desirable is some cases;build- builds the code (via gulpgulpfile.js) in development mode (generateslibanddistfolder);build:prod- builds the code (via gulpgulpfile.js) in production mode (generateslibanddistfolder);test- default project test script, defaults totest:unit;test:unit- runs unit tests;test:integration- runs it tests;test:all- runs all tests;test:circular- tests for circular dependencies;coverage- runs all tests, calculates coverage (html/csv), generates a test report (HTML and junit) and generates badges for readme;prepare-pr: same as prepare-release,lint- runs es lint on the code folder;lint-fix- tries to auto-fix the code folder;prepare-release- defines the commands to run prior to a new tag (defaults to linting, building production code, running tests and documentation generation);release- triggers a new tag being pushed to master (via./bin/tag_release.sh);clean-publish- cleans the package.json for publishing;drawings- compiles all DrawIO*.drawiofiles in theworkdocs/drawingsfolder to png and moves them to theworkdocs/resourcesfolder;uml- compiles all PlantUML*.pumlfiles in theworkdocs/umlfolder to png and moves them to theworkdocs/resourcesfolder;docs- compiles all the coverage, drawings, uml, jsdocs, and md docs into a readable web page under./docs. Will be made available at GitHub Pages;publish-docs- publishes the content of./workdocs/confluenceto confluence according to the config at./workdocs/confluence/.markdown-confluence.json. Uses markdown-confluence. Check their documentation for configuration details;
Linting
This repo comes with eslint + prettier preconfigured to the default standards.
Please configure your IDE to recognize these files and perform automatic validation and fixes on save:
- Webstorm:
- eslint recommended setup preconfigured under
.idea/jsLinters/eslint.xml - prettier recommended setup preconfigured under
.idea/prettier.xml
- eslint recommended setup preconfigured under
- VSCode(ium):
- eslint recommended setup preconfigured under
.vscode/settings.json - prettier recommended setup preconfigured under
.vscode/settings.json
- eslint recommended setup preconfigured under
Testing
Preconfigured Jest based testing:
npm run test- default repository test script. defaults totest:unit;npm run test:unit- unit tests under thetests/unitfolder without coverage;npm run test:all- include a dist/bundle test undertests/bundling(helps with circular dependencies dist test);npm run test:bundling- integration tests under thetests/integrationfolder;npm run test:circular- stores coverage results underworkdocs/coverage;npm run coverage- stores coverage & test reports underworkdocs/reports;- Coverage and test results will become part of exported docs;
- ignores
cli.tsfrom coverage since that is an executable file; - uses
jest.config.tsas its base config; - uses
workdocs/reports/jest.coverage.config.tsas its base config; - defines the coverage threshold in
workdocs/reports/jest.coverage.config.ts;
Contracts
General information
To test/debug a contract implementation first you need to deploy it, there is a basic infrastructure available to boot the contract.
In the docker/infrastructure folder, you will find this basic setup. To test/debug a contract, copy the contract’s JavaScript code into the chaincode folder.
The contract must include:
-
package.json
-
npm-shrinkwrap.json/ package-lock.json
-
Transpiled files for the contract
Transpiling a contract
If you need to transpile the contract you can use the weaver binary. An example is provided bellow pointing to a test implementation.
npx weaver compile-contract -d --contract-file ./tests/assets/contract/asset-transfer/index.ts --output-dir ./docker/infrastructure/chaincode
Booting the contract infrastructure
Run:
npm run infrastructure:up
Debuging Flow
To be able to debug the contracts there are a few changes we need to make. First on the start command needs to change to "start": "node --inspect=0.0.0.0:9229 path/to/entry/file" the the code should be adapted so it can be called via node. An example of the entry file can be found in /tests/assets/serialized-contract-debug/index.js.
After this adjustmets boot the infrastructure with the debug prepared contract. Check the ip of the instance of the contract you want to debug, copy it and when running the Attach To Remote Launch a input prompt will ask for the remote address. Paste the ip from the container and you are ready to debug. You can place breakpoints in the docker/infrastructure/chaincode folder.
Testing Flow
To test the contract you have to transpile and place it in the docker/infrastrucure/chaincode folder. Don't forget to add a package.json and a package-lock.json or npm-shrinkwrap.json file for that contract. An example of these files could be found under tests/contract/asset-transfer/*.
After the chaincode is in place you simply have to run:
npm run infrastructure:up
To reset the environment to test another contract or to clean test the same contract first destroy the current environment by running the command:
npm run infrastructure:down
When the command finishes remove the folder docker/infrastructure/storage and run the command:
git checkout docker/
This sucessfully resets the repository and you can restart the process by changing the contract to be tested or booting the infrastructure again.
Documentation
The repository proposes a way to generate documentation that while still not ideal, produces very consistent results.
There are 3 steps in generating the documentation (automated in CI):
npm run drawings- generates png files from each drawing in theworkdocs/drawingsfolder and moves them to theworkdocs/resourcesfolder (requires Docker);npm run uml- generates png files from each PlantUML diagram in theworkdocs/umlfolder and moves them to theworkdocs/resourcesfolder (requires Docker);npm run docs- this has several stages, defined under thegulp docs(gulpfile.js):- compiles the Readme file via md compile:
- enables keeping separate files for sections that are then joined into a single file;
- Allows keeping specific files in the jsdoc tutorial folder so they show up on their own menu;
- compiles the documentation from the source code using jsdoc:
- uses the better docs template with the category and component plugins
- uses the mermaid jsdoc plugin to imbue uml diagrams in the docs
- includes a nav link to the test coverage results;
- copies the jsdoc and mds to
/docs; - copies the
./workdocs/{drawings, uml, assets, resources}to./docs;
- compiles the Readme file via md compile:
The produced docs folder contains the resulting documentation;
Continuous Integration/Deployment
While the implementation for gitlab and GitHub are not perfectly matched, they are perfectly usable.
The template comes with ci/cd for :
- gitlab (with caching for performance):
- stages:
- dependencies: Installs dependencies (on
package-lock.jsonchanges, caches node modules); - build: builds the code (on
src/*changes, cacheslibanddist); - test: tests the code (on
src/*,test/*changes, cachesworkdocs/{resources, badges, coverage}); - deploy:
- deploys to package registry on a tag (public|private);
- deploys docker image to docker registry (private);
- Deploys the documentation to the repository pages;
- dependencies: Installs dependencies (on
- stages:
- github:
- jest-test: standard
install -> build -> testloop; - jest-coverage: extracts coverage from the tests;
- codeql-analysis: Code quality analysis;
- snyk-scan: Vulnerability scanning
- pages: builds the documentation and deploys to GitHub pages
- release-on-tag: issues a release when the tag does not contain
-no-cistring - publish-on-release: publishes to package registry (following the release) when the tag does not contain the
-no-cistring - Requires Variables:
- CONSECUTIVE_ACTION_TRIGGER: secret to enable actions to trigger other actions;
- NPM_TOKEN: npm registry token
- CI Pages Setup:
- Enable Pages via a GitHub action:

- Secure Workflows via GitHub action:

- Allow GitHub pages via GitHub action for tags:

- Enable Pages via a GitHub action:
- jest-test: standard
Releases
This repository automates releases in the following manner:
- run
npm run release -- <major|minor|patch|version> <message>:- if arguments are missing, you will be prompted for them;
- it will run
npm run prepare-releasenpm script; - it will commit all changes;
- it will push the new tag;
If publishing to a private repo's npm registry, make sure you add to your package.json:
{
"publishConfig": {
"<SCOPE>:registry": " https://<REGISTRY>/api/v4/projects/<PROJECT_ID>/packages/npm/"
}
}
Where:
<SCOPE>- Is the scope of your package;<REGISTRY>- your registry host;<PROJECT_ID>- you project ID number (easy to grab via UI in gitlab or by running$("meta[name=octolytics-dimension-repository_id]").getAttribute('content')in the repository page in github);
Publishing
Unless the -no-ci flag is passed in the commit message to the npm run release command, publishing will be handled
automatically by github/gitlab (triggered by the tag).
When the -no-ci flag is passed then you can:
- run
npm run publish. This command assumes :- you have previously run the
npm run release; - you have you publishing properly configured in
npmrcandpackage.json; - The token for any special access required is stored in the
.tokenfile;
- you have previously run the
Repository Structure
for-fabric
│
│ .confluence-token <-- stores confluence access token
│ .dockerignore <-- Defines files by docker in the build image
│ .dockeruser <-- stores docker registry user
│ .dockertoken <-- stores docker registry access token
│ .gitignore <-- Defines files ignored to git
│ .gitlab-ci.yml <-- CI behaviour for gitlab
│ .npmignore <-- Defines files ignored by npm
│ .nmprc <-- Defines the Npm registry for this package
│ .nmptoken <-- Defines access token for the Npm registry for this package
│ .prettierrc <-- style definitions for the project
│ .snyk <-- vulnerability scan (via snyk) config
│ .token <-- token for dependencies in private registries
│ .eslint.config.js <-- linting for the project
│ gulpfile.js <-- Gulp build scripts. used for building na other features (eg docs)
│ jest.config.ts <-- Tests Configuration file
│ LICENCE.md <-- Licence disclamer
│ package.json
│ package-lock.json
│ README.md <-- Readme File dynamically compiled from 'workdocs' via the 'docs' npm script
│ tsconfig.json <-- Typescript config file. Is overriden in 'gulpfile.js'
│
└───.github
│ │ ... <-- github workflows and templates
│
└───.run
│ │ ... <-- IDE run scripts for WebStorm
│
│└───.vscode
│ │ ... <-- IDE run scripts and configs for VSCode(ium)
│
└───bin
│ │───tag_release.cjs <-- Script to help with releases
│ │───template-setup.cjs <-- Script that runs on first npm install and configures the repo
│ └───update-scripts.cjs <-- Retrieves the most updated configuration files from the original repository
└───dist
│ │ ... <-- Dinamically generated folder containing the bundles for distribution
│
└───docs
│ │ ... <-- Dinamically generated folder, containing the compiled documentation for this repository. generated via the 'docs' npm script
│
└───lib
│ | ... <-- Dinamically generated folder containing the compiled code
│
└───src
│ │ ... <-- Source code for this repository
│
└───tests
│ │───bundling <-- Tests the result of the produced bundle
│ │───unit <-- Unit tests
│ └───integration <-- Integration tests
│
└───workdocs <-- Folder with all pre-compiled documentation
│───assets <-- Documentation asset folder
│───confluence <-- folder containing specific documentation to be synced with a confluence page
│───drawings <-- Drawio drawings that are converted to the resources folder dynamically
│───prompts <-- Used AI prompts (great for documentation and testing)
│───reports <-- Folder storing generated content (compiled uml, drawio, test reports, etc)
│ └───coverage <-- Auto generated coverage results (report ready html)
│ └───data <-- folder used as temp while genrating reports wiht attachements
│ └───html <-- test results (jest-html-reporters) complete test report with attachements
│ └───junit <-- test results (junit xml)
│ └───jest.coverage.config.ts <-- jest config collecting coverage and exporting test results (extends base config)
│───resources <-- Folder storing generated content (compiled uml, drawio, etc)
│───tutorials <-- Tutorial folder (will show up on tutorial section in generated documentation)
│───uml <-- folder containing puml files to be compiled along with the documentation
│ ... <-- Categorized *.md files that are merged to generate the final readme (via md compile)
│ jsdocs.json <-- jsdoc Documentation generation configuration file
│ Readme.md <-- Entry point to the README.md (will import other referenced md files)
│ readme-md.json <-- md Documentation generation configuration file for the README.md file
IDE Integrations
Visual Studio Code (VSCode)
For an optimal development experience in VSCode, we recommend installing the following extensions:
- ESLint – Linting made easy and integrated.
- Prettier – Code formatting with style.
- Jest – Smooth integration for running and debugging tests.
We've included a pre-configured settings.json that ensures:
- Linting and formatting are automatically applied on file save.
- Jest works seamlessly with your test suite out of the box.
Tasks & Launchers
Common tasks like build, test, and others are pre-configured as VSCode Tasks and Launch Configurations.
To access and run them:
- Open the Command Palette (
Cmd/Ctrl + Shift + P) and selectTasks: Run Task. - Or go to the Run and Debug panel, choose a configuration from the dropdown, and press ▶️.
WebStorm
For WebStorm users, everything comes integrated right out of the box 🎉
Common commands for builds, tests, and documentation generation are available in the Run/Debug configurations dropdown for quick access and execution via:
-
Jest integration:
tests/Unit Tests- Runs all unit tests (analog totest:unit)tests/Integration Tests- Runs all integration tests (analog totest:integration)tests/Bundling Tests- Runs the dist and bundling tests (analog totest:bundling)All Tests- Runs all tests (analog totest:all)
-
Node integration:
repo/docs- Builds documentation (analog todocs)repo/coverage- runstest:all, collects coverage (csv, HTML), generates test reports (junit, HTML) (analog tocoverage)repo/uml- builds uml into png files (analog touml)repo/test:circular- test code for circular dependencies (analog totest:circular)repo/lint-fix- tries to fix linting issues (analog tolint-fix)repo/drawings- compiles draw.io files to png (one per page) (analog todrawings)repo/flash-forward- updates all dependencies to latest versions (analog toflash-forward)repo/update-scripts- runs cli to update repo's configs (CI, Doc boilerplate, Linting, Style, etc) via it's template repository (analog todrawings)build:prod-builds code in production mode (minify, uglify, doc extraction, and no source-map for bundled production)build-builds code in development mode
Considerations
- Setup for node 20, but will work at least with 16;
- Requires docker to build documentation (drawings and PlantUML)
Coding Principles
- group similar functionality in folders (analog to namespaces but without any namespace declaration)
- one class per file;
- one interface per file (unless interface is just used as a type);
- group types as other interfaces in a types.ts file per folder;
- group constants or enums in a constants.ts file per folder;
- group decorators in a decorators.ts file per folder;
- group pure/utilitarian functions in a utils.ts file per folder, or create a dedicated file per related functionality. Try to limit the export of these outside the package.
- always import from the specific file, never from a folder or index file (exceptions for dependencies on other packages)
- All classes, interfaces, constants and types should always be exported